package it.unica.informatica.enotes.database;

import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;

/**
 * This class provides all operations related to visualization and search of notes.
 *
 * @author Massimiliano Meles
 * @version 1.0
 */
public class NoteDatabaseProvider extends ContentProvider {

   // MIME types used for searching tags
   public static final String TAG_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/it.unica.informatica.enotes.database";
   private static final int GET_TAG = 1;
   private static final int SEARCH_SUGGEST = 2;
   //Initialization of UriMatcher to parse URIs
   private static final UriMatcher sURIMatcher = buildUriMatcher();

    /* *******************************************************************************************
    *                                     VARIABLES AND CONSTANTS                                *
    * *******************************************************************************************/


   //Permission used to use DB
   public static String AUTHORITY = "it.unica.informatica.enotes.database.NoteDatabaseProvider";
   private DatabaseAdapter databaseAdapter;


   /**********************************************************************************************
    *                                  METHODS RELATED TO URIMATCHER                             *
    **********************************************************************************************/

   /**
    * Create a UriMatcher for search suggestion.
    */
   private static UriMatcher buildUriMatcher() {
      UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
      //Used to get tags
      matcher.addURI(AUTHORITY, "noteDatabase/#", GET_TAG);
      //Used to get tags suggestions
      matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);

      return matcher;
   }

   /**
    * This method is used by the Provider to get the type of each uri
    *
    * @param uri The uri used to indicate the action desired
    */
   public String getType(Uri uri) {
      switch (sURIMatcher.match(uri)) {
         case GET_TAG:
            return TAG_MIME_TYPE;
         case SEARCH_SUGGEST:
            return SearchManager.SUGGEST_MIME_TYPE;
         default:
            throw new IllegalArgumentException("Unknown URL " + uri);
      }
   }



    /* *******************************************************************************************
    *                                  METHODS RELATED TO SUGGESTION                             *
    * *******************************************************************************************/


   @Override
   public boolean onCreate() {
      databaseAdapter = new DatabaseAdapter(getContext());
      databaseAdapter.open();
      return true;
   }

   /**
    * This method parse the uri, and call the right method based on it.
    *
    * @param uri           the uri indicate the action and the item to retrieve
    * @param projection    The columns to return for each row
    * @param selection     A selection criteria to apply when filtering rows. If null then all rows are included.
    * @param selectionArgs If in selection there is ?s , it's replaced by selectionArgs
    * @param sortOrder     Order for the sorting
    */
   @Override
   public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
      switch (sURIMatcher.match(uri)) {
         //If the UriMatcher for the uri return SEARCH_SUGGEST, query call getSuggestions to get all tags in suggestion list
         case SEARCH_SUGGEST:
            //If no arguments in defined, throw an exception
            if (selectionArgs == null)
               throw new IllegalArgumentException("No selectionArgs provided for the Uri: " + uri);
            return getSuggestions(selectionArgs[0]);

         //If the UriMatcher for the uri return  GET_TAG, query call getTag to retrieve a tag from a rowId
         case GET_TAG:
            return getTag(uri);

         default:
            throw new IllegalArgumentException("Unknown Uri: " + uri);
      }
   }

   /**
    * This method create an array of columns name and through the databaseAdapter returns a cursor with all suggestion for tag list
    *
    * @param query The partial tag inserted for witch it's need to find suggestion
    */
   private Cursor getSuggestions(String query) {
      query = query.toLowerCase();
      String[] columns = new String[]{
              BaseColumns._ID,
              DatabaseHelper.KEY_TAG,
              SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID };

      return databaseAdapter.getNoteMatches(query, columns);
   }

   /**
    * This method create an array of columns name and through the databaseAdapter returns a cursor with the tag founded at rowId
    *
    * @param uri The uri used to indicate the action GET_TAG and the rowId of the tag
    */
   private Cursor getTag(Uri uri) {
      String rowId = uri.getLastPathSegment();
      String[] columns = new String[]{
              DatabaseHelper.KEY_TAG };

      return databaseAdapter.getTag(rowId, columns);
   }


    /* *******************************************************************************************
    *                                  NEEDED OVERRIDED                                          *
    * *******************************************************************************************/


    /*Insert or delete of a tag is handled by adapter, no need to do that from provider*/
   @Override
   public Uri insert(Uri uri, ContentValues values) {
      throw new UnsupportedOperationException();
   }

   @Override
   public int delete(Uri uri, String selection, String[] selectionArgs) {
      throw new UnsupportedOperationException();
   }

   @Override
   public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
      throw new UnsupportedOperationException();
    }
}
